﻿

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using RBAC_Uthorization.API.DTO;
using RBAC_Uthorization.Domain;
using System.Net;
using System.Net.Sockets;


namespace RBAC_Uthorization.API.Extensions
{
    public class ExceptionFilter : IExceptionFilter
    {
        private readonly ILogger<ExceptionFilter> _logger;
        private static readonly string Hostname;
        private static readonly string IpAddress;

        static ExceptionFilter()
        {
            // 获取并缓存主机名和 IP 地址
            Hostname = Dns.GetHostName();
            var hostentry = Dns.GetHostEntry(Hostname);
            var ipaddress = hostentry.AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);
            IpAddress = ipaddress?.ToString() ?? "未知的 IP";
        }

        public ExceptionFilter(ILogger<ExceptionFilter> logger)
        {
            _logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            // 获取异常信息
            var exception = context.Exception;
            var exceptionMessage = exception.Message;
            var stackTrace = exception.StackTrace;

            // 获取请求信息
            var requestPath = context.HttpContext.Request.Path;
            var requestMethod = context.HttpContext.Request.Method;

            // 记录错误日志，包括 IP 地址、请求路径、请求方法、异常消息和堆栈跟踪
            _logger.LogError("异常发生：\n" +
                             $"主机名: {Hostname}\n" +
                             $"IP地址: {IpAddress}\n" +
                             $"请求路径: {requestPath}\n" +
                             $"请求方法: {requestMethod}\n" +
                             $"异常消息: {exceptionMessage}\n" +
                             $"堆栈跟踪: {stackTrace?.Substring(0, 50)}");

            // 返回错误信息
            var errorResponse = new ApiResult<string>
            {
                Code = ResultCode.Fail,
                Message = "服务器内部错误，请稍后再试",

            };
            context.Result = new JsonResult(errorResponse);


            // 标记异常已处理，防止进一步传播
            context.ExceptionHandled = true;
        }
    }
}
